package de.gwtprime.client.widgets;

import java.util.Set;

import com.google.gwt.core.shared.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.FlowPanel;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.SimplePanel;
import com.google.gwt.user.client.ui.Widget;
import com.google.web.bindery.requestfactory.shared.Receiver;
import com.google.web.bindery.requestfactory.shared.Request;
import com.google.web.bindery.requestfactory.shared.ServerFailure;

import de.gwtprime.client.ClientFactory;
import de.gwtprime.client.PrimeRequestFactory;
import de.gwtprime.client.event.AnswerAddedEvent;
import de.gwtprime.client.event.ApplyTabHeightEvent;
import de.gwtprime.client.event.QuestionOnTypeEvent;
import de.gwtprime.client.event.handler.AnswerAddedEventHandler;
import de.gwtprime.client.event.handler.QuestionOnTypeEventHandler;
import de.gwtprime.client.presenter.VoteControlPresenterQuestionImpl;
import de.gwtprime.client.user.ACLManager;
import de.gwtprime.client.user.ACLManager.PrimeUIElement;
import de.gwtprime.client.util.AppUtils;
import de.gwtprime.shared.requestFactory.AnswerProxy;
import de.gwtprime.shared.requestFactory.QuestionProxy;
import de.gwtprime.shared.requestFactory.request.QuestionRequest;

public class QuestionWidget extends Composite {

	interface QuestionWidgetUiBinder extends UiBinder<Widget, QuestionWidget>{};
	QuestionWidgetUiBinder uiBinder = GWT.create(QuestionWidgetUiBinder.class);
	
	@UiField Label title;
	@UiField HTML text;
	@UiField Label previewLbl;
	@UiField Label userName;
	@UiField Button questionDeleteBtn;
	@UiField Button editBtn;
	
	@UiField Label noAnswersLbl;
	/**
	 * List all answers for this questions
	 */
	@UiField FlowPanel answers;
	@UiField SimplePanel editQuestionWidget;
	
	@UiField SimplePanel addAnswerWidget;
	
	// <h2>Deine Antwort:</h2>
	@UiField HTML yourAnswerTitle;
	
	@UiField SimplePanel answerPreviewWidget;
	
	@UiField SimplePanel voteControl;
	
	@UiField Label postedByLbl;
	
	@UiField Label answersTitle;
	
	@UiField TooltipButton showAddAnswerWidget;
	
	private QuestionProxy question;
	
	/**
	 * Question preview does not show answers, add answer form etc.
	 */
	private boolean isPreview = false;
	
	public QuestionWidget(final QuestionProxy question, final ClientFactory clientFactory) {
		initWidget(uiBinder.createAndBindUi(this));
		yourAnswerTitle.setVisible(false);
		noAnswersLbl.setVisible(false);
		
		answersTitle.setText("Antworten: ");
		postedByLbl.setText("Author: ");
		
		if(question == null){
			this.question = clientFactory.getRequestFactory().questionRequest().create(QuestionProxy.class);
			isPreview = true;
		}else{
			this.question = question;
		}
		
		previewLbl.setVisible(isPreview);
		
		if(isPreview){
			previewLbl.setText("Preview:");
			
			answersTitle.setVisible(false);
			postedByLbl.setVisible(false);
			userName.setVisible(false);
			
			addAnswerWidget.setVisible(false);
		}
		title.setText(this.question.getTitle());
		text.setHTML(AppUtils.editForClient(this.question.getText(), this.question.getImages()));
		questionDeleteBtn.setText("delete");
		
		questionDeleteBtn.setVisible(ACLManager.hasUserAccess(clientFactory.getUser(), PrimeUIElement.QuestionDeleteBtn));
		
		
		Set<AnswerProxy> answersSet = this.question.getAnswers();
		if(answersSet!=null && answersSet.size()!=0){
			for(AnswerProxy answer: answersSet){
				answers.add(new AnswerWidget(clientFactory, answer, this.question));
			}
		}else{
			noAnswersLbl.setText("Keine Antworten");
			noAnswersLbl.setVisible(!isPreview);
		}
		
		userName.setText(this.question.getUser()==null ? "-" : this.question.getUser().getName());
		
		clientFactory.getEventBus().addHandler(AnswerAddedEvent.TYPE, new AnswerAddedEventHandler() {
			
			@Override
			public void onAnswerAdded(AnswerAddedEvent event) {

				onAnswerAddedEvent(clientFactory, event);
				
			}

			private void onAnswerAddedEvent(final ClientFactory clientFactory,
					AnswerAddedEvent event) {
				noAnswersLbl.setVisible(false);
				showAddAnswerWidget.setVisible(true);
				yourAnswerTitle.setVisible(false);
				
				answerPreviewWidget.setVisible(false);
				
				answers.add(new AnswerWidget(clientFactory, event.getAnswer(), QuestionWidget.this.question));
				clientFactory.getEventBus().fireEvent(new ApplyTabHeightEvent());
			}
		});
		
		questionDeleteBtn.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {

				QuestionWidget.this.setVisible(false);
				final PrimeRequestFactory requestFactory = clientFactory
						.getRequestFactory();
				final QuestionRequest request = requestFactory
						.questionRequest();
				Request<Void> createReq2 = request.remove().using(QuestionWidget.this.question);

				createReq2.fire(new Receiver<Void>() {
					@Override
					public void onSuccess(Void list) {
						AppUtils.log("Question deleted");
					}

					@Override
					public void onFailure(ServerFailure error) {
						AppUtils.log("Failed to delete question");
					}
				});
				
			}
		});
		
		addAnswerWidget.setVisible(false);
		answerPreviewWidget.setVisible(false);
		
		showAddAnswerWidget.enableFromUser(clientFactory, PrimeUIElement.AnswerAdd);
		showAddAnswerWidget.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				
				if(!showAddAnswerWidget.checkEnabledStateAndShowMessage(event)){
					return;
				}
				addAnswerWidget.clear();
				answerPreviewWidget.clear();
				
				addAnswerWidget.add(new AddAnswerWidget(question, clientFactory, null));
				answerPreviewWidget.add(new AnswerWidget(clientFactory, null, question)); 
				
				yourAnswerTitle.setHTML("<h2>Deine Antwort:</h2>");
				yourAnswerTitle.setVisible(!isPreview);
				
				showAddAnswerWidget.setVisible(false);
				addAnswerWidget.setVisible(!isPreview);
				answerPreviewWidget.setVisible(true);
				
			}
		});
		
		// control widget
		ArticleSectionControlWidget controlWidget = new ArticleSectionControlWidget(clientFactory);
		VoteControlPresenterQuestionImpl controlPresenter = new VoteControlPresenterQuestionImpl(this.question, clientFactory, controlWidget);
		controlWidget.initWidget(controlPresenter);
		controlWidget.setShowCompleteVoteBtn(false);
	
		if(!isPreview)
			voteControl.add(controlWidget);
		
		editBtn.setVisible(clientFactory.getUser()!=null && (clientFactory.getUser().isAdmin() || (this.question.getUser() != null && clientFactory.getUser().getEmail().equals(this.question.getUser().getEmail()))));
		editBtn.setText("Frage bearbeiten");
		editBtn.addClickHandler(new ClickHandler() {
			
			@Override
			public void onClick(ClickEvent event) {
				editQuestionWidget.clear();
				editQuestionWidget.add(new AddQuestionWidget(QuestionWidget.this.question, null, clientFactory));
				
			}
		});
		
		
		clientFactory.getEventBus().addHandler(QuestionOnTypeEvent.TYPE, new QuestionOnTypeEventHandler() {
			
			@Override
			public void onType(QuestionOnTypeEvent event) {
				title.setText(event.getTitle());
				text.setHTML(AppUtils.editForClient(event.getText(), event.getImages()));
				
				clientFactory.getEventBus().fireEvent(new ApplyTabHeightEvent());
				
			}
		});
		
	}

	public boolean isPreview() {
		return isPreview;
	}

	public void setPreview(boolean isPreview) {
		this.isPreview = isPreview;
	}
	
	
}
